// class版本的自定义Promise
class Promise {

    // 构造方法
    constructor(excutor){
        // 初始化状态属性值为pending
        this.PromiseState = "pending";
        // 初始化结果属性值为undefined
        this.PromiseResult = undefined;
        // 声明一个属性用于存放then没有执行的回调函数
        this.callbacks = [];
        
        // 声明内部成功函数
        const success = (v) => {
            // 若当前状态不是等待pending，则退出
            if(this.PromiseState != "pending"){
                return;
            }
            this.PromiseState = "fulfilled";
            this.PromiseResult = v;
            // 询问callbacks属性中是否存在需要执行回调（因为延迟导致没有执行的）
            if(this.callbacks.length > 0){
                this.callbacks.forEach(item =>{
                    item.ok(this.PromiseResult);
                });
            }
            
        }

        // 声明内部失败函数
        const error = (r) => {
            // 若当前状态不是等待pending，则退出
            if(this.PromiseState != "pending"){
                return;
            }
            this.PromiseState = "rejected";
            this.PromiseResult = r;
            // 询问callbacks属性中是否存在需要执行回调（因为延迟导致没有执行的）
            if(this.callbacks.length > 0){
                this.callbacks.forEach(item =>{
                    item.ng(this.PromiseResult);
                });
            }
        }
        try {
            // 调用执行器
            excutor(success,error);
        } catch (err) {
            error(err.message);
        }
    }

    // 定义promise的then方法
    then(onFulfilled, onRejected){
        return new Promise((resolve, reject) => {
            //声明一个函数 『handle 处理的意思』
            const handle = (type) => {
                try {
                    if(type === undefined){
                        reject(this.PromiseResult);
                        return;
                    }
                    // 获取成功回调的返回值
                    let res = type(this.PromiseResult);
                    // 判断返回结果是否是一个promise对象
                    if(res instanceof Promise){
                        //若res是promise对象,那么通过then()来获取状态信息以及值
                        res.then(v => {
                            resolve(v);
                        },r => {
                            reject(r);
                        });
                    } else {
                        // 若res是非promise的任意值,那么调用resolve()设置fulfilled, 
                        // 并将当前res作为value为返回的值
                        resolve(res);
                    }
                } catch (err) {
                    reject(err.message);
                }
            }
            // 根据当前promise对象的状态属性值来执行对应的回调函数
            if(this.PromiseState == "fulfilled"){
                // 调用上面的内部函数，实现成功状态的回调调用
                setTimeout(()=>{ // 异步操作
                    handle(onFulfilled);
                });
                
            }
            if(this.PromiseState == "rejected"){
                setTimeout(()=>{ // 异步操作
                    handle(onRejected);
                });
            }
            // 判断当前promise对象的状态是否是等待pending
            if(this.PromiseState == "pending"){
                // 将当前的回调函数保留下来，存到callbacks属性中
                this.callbacks.push({
                    ok:()=>{handle(onFulfilled);},
                    ng:()=>{handle(onRejected);} 
                });
            }
        });
    }

    // 为promise添加catch方法
    catch(onRejected){
        // 此方法的功能是then的一半，所以我们可以执行调用then的一半就可以了
        return this.then(undefined, onRejected);
    }

    // 为Promise类添加静态方法resolve
    static resolve(value){
        return new Promise((resolve, reject)=>{
            //判断
            if(value instanceof Promise){
                //value 是 promise 对象
                value.then(resolve, reject);
            }else{
                //value 不是 promise 对象
                resolve(value);
            }
        });
    }

    // 为Promise类添加静态方法reject
    static reject(value){
        return new Promise((resolve, reject)=>{
            //判断
            reject(value);
        });
    }

    // 为Promise直接添加静态all方法，完成all()的功能
    static all(promises){
        // 返回一个Promise对象
        return new Promise((resolve, reject) => {
            const data = []; // 声明数组变量,用于存放每次promise成功的结果.  
            // 遍历所有的Promise参数对象
            promises.forEach(item => {
                // 调用每个promise对象的then方法
                item.then(v =>{
                    console.log("成功", v);
                    // 将成功的结果添加到数组data
                    data.push(v);
                    // 判断所有的promise都是成功， 且结果都放到了data中
                    if( data.length === promises.length){
                        resolve(data);
                    }
                }, r => {
                    console.log("失败", r);
                    reject(r);
                });
            });
        });
        
    }

    // 为Promise直接添加静态race方法，完成race()的功能
    static race(promises){
        // 返回一个Promise对象
        return new Promise((resolve, reject) => {
            // 遍历所有的Promise参数对象
            promises.forEach(item => {
                // 调用每个promise对象的then方法
                item.then(v =>{
                    resolve(v);
                }, r => {
                    reject(r);
                });
            });
        });
        
    }
}





